package com.mall.business.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mall.business.domain.*;
import com.mall.business.service.*;
import com.mall.common.annotation.RepeatSubmit;
import com.mall.common.core.controller.BaseController;
import com.mall.common.core.domain.AjaxResult;
import com.mall.common.core.domain.entity.SysDictData;
import com.mall.common.core.domain.entity.SysUser;
import com.mall.common.core.page.TableDataInfo;
import com.mall.common.exception.ServiceException;
import com.mall.common.utils.*;
import com.mall.system.service.ISysDictDataService;
import com.mall.system.service.ISysUserService;
import com.mall.system.service.impl.SysUserServiceImpl;
import org.apache.catalina.security.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static java.awt.Color.pink;

/**
 * 接口
 */
@RestController
@RequestMapping("/webApi")
public class ApiController extends BaseController {

    @Autowired
    private ITOrderPjService tOrderPjService;


    @Autowired
    private ITPinkService tPinkService;


    @Autowired
    private ITPtActiveService tPtActiveService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ITProductService productService;


    @Autowired
    private ITSeckillService tSeckillService;

    @Autowired
    private ITAwardProductService tAwardProductService;

    @Autowired
    private ITCartService tCartService;

    @Autowired
    private ISysDictDataService iSysDictDataService;












    /**
     * 评价列表
     */

    @RequestMapping("/nologin/getPjList")
    public TableDataInfo getPjList(TOrderPj vo) {
        List<TOrderPj> tOrderPjs = tOrderPjService.selectTOrderPjList(vo);
        return getDataTable(tOrderPjs);
    }

    /**
     * 发团
     */
    @PostMapping("/addPink")
    public AjaxResult addPink(@RequestBody AddTPinkDTO dto) {
        String ptActiveId = dto.getPtActiveId();
        TPtActive ptactive = tPtActiveService.getById(ptActiveId);
        // 有效时长(小时)
        Integer yxTime = ptactive.getYxTime();
        String productId = ptactive.getProductId();
        String pinkId = dto.getPinkId();
        if (!StringUtils.isEmpty(pinkId)) {
            // 参团
            String userIdStr = SecurityUtils.getUserIdStr();
            if (tPinkService.getUserIsPink(pinkId, userIdStr)) {
                return AjaxResult.error("您已参团，无需重复参团");
            }
            TPink teampink = tPinkService.getById(pinkId);
            String status = teampink.getStatus();
            if ("2".equals(status)) {
                return AjaxResult.error("拼团已完成");
            }
            if ("3".equals(status)) {
                return AjaxResult.error("拼团超时取消");
            }
            List<TPink> pinkList = tPinkService.getPinkListByTeamId(ptActiveId, pinkId);
            pinkList.add(teampink);
            //拼团剩余人数
            int count = teampink.getPeopleNum() - (CollUtil.isEmpty(pinkList) ? 0 : pinkList.size());

            TPink newTpink = new TPink();
            newTpink.setProductId(productId);
            newTpink.setPtActiveId(ptActiveId);
            newTpink.setPeopleNum(teampink.getPeopleNum());
            newTpink.setStartTime(DateUtils.getNowDate());
            newTpink.setEndTime(null);
            newTpink.setTeamId(pinkId);
            newTpink.setUserId(SecurityUtils.getUserIdStr());
            newTpink.setStatus("1");
            tPinkService.save(newTpink);
            if (count == 1) {
                tPinkService.pinkSuccess(pinkId);
            }

        } else {
            TPink newTpink = new TPink();
            newTpink.setProductId(productId);
            newTpink.setPtActiveId(ptActiveId);
            newTpink.setPeopleNum(ptactive.getPeopleNum());
            newTpink.setStartTime(DateUtils.getNowDate());
            // 通过开始时间和 有效时长计算结束时间
            newTpink.setEndTime(DateUtil.offsetHour(DateUtils.getNowDate(), yxTime));
            newTpink.setUserId(SecurityUtils.getUserIdStr());
            // 团长id
            newTpink.setTeamId("0");
            newTpink.setStatus("1");
            tPinkService.save(newTpink);
            return AjaxResult.success(newTpink);
        }
        return AjaxResult.success();
    }

    /**
     * 拼团明细
     */
    @PostMapping("/pinkInfo")
    public AjaxResult pinkInfo(String pinkId) {

        int isOk = 0;//判断拼团是否完成
        int userBool = 0;//判断当前用户是否在团内  0未在 1在
        int pinkBool = 0;//判断拼团是否成功  0未成功 1成功
        TPink teampink = tPinkService.selectTPinkById(pinkId);
        String ptActiveId = teampink.getPtActiveId();
        TPtActive ptactive = tPtActiveService.getById(ptActiveId);
        if (ptactive == null) {
            return AjaxResult.error("活动不存在");
        }
        String status = ptactive.getStatus();
        if ("0".equals(status)) {
            return AjaxResult.error("活动未开启");
        }

        List<TPink> pinkList = tPinkService.getPinkListByTeamId(ptActiveId, pinkId);
        pinkList.add(teampink);

        //拼团剩余人数
        int count = teampink.getPeopleNum() - (CollUtil.isEmpty(pinkList) ? 0 : pinkList.size());

        if ("2".equals(teampink.getStatus())) {//已完成
            isOk = 1;
            pinkBool = 1;
        } else if ("3".equals(teampink.getStatus())) {
            // 未完成
            isOk = 0;
            // 失败
            pinkBool = 0;
        } else if ("1".equals(teampink.getStatus())) {//进行中
            if (count < 1) {// 拼团已完成
                isOk = 1;
                pinkBool = 1;
                // 拼团完成处理
                tPinkService.pinkSuccess(pinkId);
            }
        }
        List<String> uidList = pinkList.stream().map(TPink::getUserId).collect(Collectors.toList());
        if (uidList.contains(SecurityUtils.getUserIdStr())) {
            userBool = 1;
        }
        // 当前用户的拼团信息
        TPink currPinkByTeamId = tPinkService.getCurrPinkByTeamId(ptActiveId, pinkId);
        PinkInfoVo build = PinkInfoVo.builder()
                .count(count)
                .isOk(isOk)
                .currPink(currPinkByTeamId)
                .pinkAll(pinkList)
                .pinkBool(pinkBool)
                .pinkT(teampink)
                .userBool(userBool)
                .build();
        return AjaxResult.success(build);
    }

    /**
     * 拼团列表(分页)
     */
    @GetMapping("/nologin/getPinkList")
    public AjaxResult getPinkList(TPink dto) {
        startPage();
        dto.setTeamId("0");
        dto.setStatusList(Arrays.asList("1"));
        List<TPink> pinkList = tPinkService.selectTPinkList(dto);
        String currUserId = dto.getCurrUserId();
        for (int i = 0; i < pinkList.size(); i++) {
            int userBool = 0;
            TPink teampink = pinkList.get(i);
            List<TPink> memberList = tPinkService.getPinkListByTeamId(teampink.getPtActiveId(), teampink.getId());
            memberList.add(teampink);
            int count = teampink.getPeopleNum() - (CollUtil.isEmpty(memberList) ? 0 : memberList.size());
            // 还差几人
            pinkList.get(i).setCount(count);
            //
            List<String> uidList = memberList.stream().map(TPink::getUserId).collect(Collectors.toList());
            if (uidList.contains(currUserId)) {
                userBool = 1;
            }
            pinkList.get(i).setUserBool(userBool);
        }
        return AjaxResult.success(pinkList);
    }


    /**
     * 拼团活动列表(分页)
     */
    @GetMapping("/nologin/getPtActiveList")
    public TableDataInfo getPtActiveList(TPtActive dto) {
        startPage();
        dto.setStatus("1");
        List<TPtActive> tPtActives = tPtActiveService.selectTPtActiveListApp(dto);
        return getDataTable(tPtActives);
    }

    /**
     * 拼团活动--详情
     */
    @GetMapping("/nologin/getPtActiveDetail")
    public AjaxResult getPtActiveDetail(TPtActive dto) {
        TPtActive tPtActive = tPtActiveService.selectTPtActiveByIdApp(dto.getId());
        String productId = tPtActive.getProductId();
        TProduct tProduct = productService.selectTProductById(productId);
        tPtActive.setProduct(tProduct);
        return AjaxResult.success(tPtActive);
    }


    /**
     * 取消拼团
     */
    @PostMapping("/removePink")
    public void removePink(TPink dto) {
        // pinkId
        String pinkId = dto.getId();
        TPink pink = tPinkService.getById(pinkId);
        String ptActiveId = pink.getPtActiveId();
        if (pink == null) {
            throw new ServiceException("拼团不存在或已经取消");
        }
        if ("2".equals(pink.getStatus())) {
            throw new ServiceException("拼团已经完成不能取消");
        }
        if ("3".equals(pink.getStatus())) {
            throw new ServiceException("已经取消");
        }
        String teamId = pink.getTeamId();
        if ("0".equals(teamId)) {
            // 成员
            List<TPink> memeberList = tPinkService.getPinkListByTeamId(ptActiveId, pinkId);
            if (memeberList.size() > 0) {
                String nextTeamId = "";
                for (int i = 0; i < memeberList.size(); i++) {
                    TPink menber = memeberList.get(i);
                    if (i == 0) {
                        // 团长
                        menber.setTeamId("0");
                        tPinkService.updateById(menber);
                        nextTeamId = menber.getId();
                    } else {
                        // 团员
                        menber.setTeamId(nextTeamId);
                        tPinkService.updateById(menber);
                    }
                }
            }
            pink.setStatus("3");
            pink.setRemark("主动取消");
            tPinkService.updateById(pink);

        } else {
            pink.setStatus("3");
            pink.setRemark("主动取消");
            tPinkService.updateById(pink);
        }
    }

    /**
     * 秒杀活动列表
     */
    @GetMapping("/nologin/getSeckillList")
    public TableDataInfo getSeckillList(TSeckill dto) {
        startPage();
        dto.setStatus("1");
        List<TSeckill> tSeckillList = tSeckillService.selectTSeckillListApp(dto);
        return getDataTable(tSeckillList);
    }

    /**
     * 秒杀活动--详情
     */
    @GetMapping("/nologin/getSkillDetail")
    public AjaxResult getSkillDetail(TSeckill dto) {
        TSeckill tSeckill = tSeckillService.selectTSeckillByIdApp(dto.getId());
        String productId = tSeckill.getProductId();
        TProduct tProduct = productService.selectTProductById(productId);
        tSeckill.setProduct(tProduct);
        return AjaxResult.success(tSeckill);
    }

    @Autowired
    private ITCouponService itCouponService;

    @Autowired
    private ITCouponUserService couponUserService;

    /**
     * 平台优惠券列表（分页）
     */
    @GetMapping("/getPtCounonList")
    public TableDataInfo getPtCounonList(TCoupon dto) {
        startPage();
        dto.setStatus("1");
        String[] split = ("2,3").split(",");
        List<String> strings = Arrays.asList(split);
        dto.setTypeList(strings);
        List<TCoupon> tCoupons = itCouponService.selectTCouponListApp(dto);
        for (int i = 0; i < tCoupons.size(); i++) {
            TCoupon tCoupon = tCoupons.get(i);
            TCouponUser  tCouponUser = new TCouponUser();
            tCouponUser.setCouponId(tCoupon.getId());
            tCouponUser.setUserId(SecurityUtils.getUserIdStr());
            List<TCouponUser> tCouponUsers = couponUserService.selectTCouponUserList(tCouponUser);
            if (!CollUtil.isEmpty(tCouponUsers)) {
                tCoupons.get(i).setIsLq("1");
            }else{
                tCoupons.get(i).setIsLq("0");
            }
        }
        return getDataTable(tCoupons);
    }

    /**
     * 领取优惠券
     */
    @PostMapping("/saveUserCounon")
    public AjaxResult saveUserCounon(@RequestBody TCoupon dto) {
        TCouponUser couponUser = new TCouponUser();
        couponUser.setCouponId(dto.getId());
        couponUser.setUserId(SecurityUtils.getUserIdStr());
        List<TCouponUser> tCouponUsers = couponUserService.selectTCouponUserList(couponUser);
        if (!CollUtil.isEmpty(tCouponUsers)) {
            throw new ServiceException("已经领取过了");
        }
        TCoupon coupon = itCouponService.getById(dto.getId());

        TCouponUser tCouponUser = new TCouponUser();
        tCouponUser.setCouponId(coupon.getId());
        tCouponUser.setUserId(SecurityUtils.getUserIdStr());
        tCouponUser.setName(coupon.getName());
        tCouponUser.setMoney(coupon.getMoney());
        tCouponUser.setStartDate(coupon.getYxStartDate());
        tCouponUser.setEndDate(coupon.getYxEndDate());
        tCouponUser.setType(coupon.getType());
        tCouponUser.setStatus("0");
        couponUserService.save(tCouponUser);
        return AjaxResult.success();
    }

    @Autowired
    private ITConfigService tConfigService;
    /**
    *
    * 抽奖
    *
    *
    */
    @PostMapping("/getAward")
    public AjaxResult getAward() {

        String award_socre = tConfigService.getConfigValue("award_socre");
        BigDecimal totalScore = tSocreService.getTotalScore();
        if(totalScore.compareTo(new BigDecimal(award_socre))<0){
            return AjaxResult.error("积分不足");
        }
        TSocre tsocre = new TSocre();
        tsocre.setScore(new BigDecimal(award_socre).negate());
        tsocre.setUserId(SecurityUtils.getUserIdStr());
        tsocre.setSrType("2");
        tsocre.setRemark("抽奖减积分");
        tSocreService.save(tsocre);

        String award_lv = tConfigService.getConfigValue("award_lv");
        TAwardProduct dto = new TAwardProduct();
        dto.setStatus("1");
        List<TAwardProduct> tAwardProducts = tAwardProductService.selectTAwardProductList(dto);
        for (int i = 0; i < tAwardProducts.size(); i++) {
            TAwardProduct tAwardProduct = tAwardProducts.get(i);
            TProduct tProduct = productService.selectTProductById(tAwardProduct.getProductId());
            tAwardProduct.setProduct(tProduct);
        }
        // 从tAwardProducts 中抽奖，设置抽奖的概率为30%,如果中奖返回产品
        // 设置抽奖的概率为30%
        double winningProbability = Double.parseDouble(award_lv);
        Random random = new Random();
        // 判断是否中奖
        if (random.nextDouble() < winningProbability) {
            // 中奖，从 tAwardProducts 中随机选择一个产品
            int randomIndex = random.nextInt(tAwardProducts.size());
            TAwardProduct winningProduct = tAwardProducts.get(randomIndex);
            return AjaxResult.success(winningProduct);
        } else {
            // 未中奖
            return AjaxResult.error("未中奖");
        }
    }

    @Autowired
    private ITSocreService tSocreService;




    /**
     *
     * 抽奖减积分
     *
     */
    @PostMapping("/saveAwardUserScore")
    public AjaxResult saveAwardUserScore(@RequestBody TSocre dto) {
        BigDecimal totalScore = tSocreService.getTotalScore();
        if(totalScore.compareTo(BigDecimal.ZERO)==0){
            return AjaxResult.error("积分不足");
        }
        TSocre tsocre = new TSocre();
        if(totalScore.compareTo(dto.getScore())<0){
            tsocre.setScore(totalScore.negate());
        }else{
            tsocre.setScore(dto.getScore().negate());
        }
        tsocre.setUserId(SecurityUtils.getUserIdStr());
        tsocre.setSrType("2");
        tsocre.setRemark("抽奖减积分");
        tSocreService.save(tsocre);
        return  AjaxResult.success();
    }


    /**
     *
     * 获取配置信息
     *
     */
    @GetMapping("/nologin/getpzInfo")
    public  AjaxResult  getpzInfo(){
        TConfig  config =new TConfig();
        List<TConfig> tConfigs = tConfigService.selectTConfigList(config);
        return  AjaxResult.success(tConfigs);

    }

    /**
     * 购物车
     */
    @RepeatSubmit
    @PostMapping("/addCart")
    public AjaxResult addCart(@Validated @RequestBody TCart cart) {
        try {
            // 检查购物车是否已经存在
            if (isCartExist(cart)) {
                return AjaxResult.error("购物车已经存在");
            }
            cart.setUserId(SecurityUtils.getUserIdStr());
            return toAjax(tCartService.save(cart));
        } catch (Exception e) {
            // 异常处理，返回友好的错误消息
            return AjaxResult.error("操作失败，请稍后尝试");
        }
    }

    /**
     * 检查购物车是否已经存在
     */
    private boolean isCartExist(TCart tGwc) {
        QueryWrapper<TCart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", SecurityUtils.getUserIdStr());
        queryWrapper.eq("product_id", tGwc.getProductId());
        Long count = tCartService.count(queryWrapper);
        // 对查询结果进行检查
        return count > 0;
    }

    /**
     * 修改购物车数量
     */
    @RepeatSubmit
    @PostMapping("/updateGwc")
    public AjaxResult updateGwc(@RequestBody TCart cart) {

        // 检查购物车商品id是否为空
        if (StringUtils.isEmpty(cart.getId())) {
            return AjaxResult.error("获取参数失败");
        }
        // 根据id获取购物车商品，更新数量
        TCart byId = tCartService.getById(cart.getId());
        if (byId == null) {
            return AjaxResult.error("购物车商品不存在");
        }
        byId.setCartNum(cart.getCartNum());
        tCartService.updateById(byId);
        return AjaxResult.success("操作成功");

    }

    /**
     * 删除购物车
     */
    @DeleteMapping("/removeGwc/{ids}")
    public AjaxResult removeGwc(@PathVariable String[] ids) {
        tCartService.removeByIds(Arrays.asList(ids));
        return success();
    }

    /**
     * 清空用户购物车
     */
    @DeleteMapping("/removeGwcUser")
    public AjaxResult removeGwcUser() {
        QueryWrapper<TCart> queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", SecurityUtils.getUserIdStr());
        tCartService.remove(queryWrapper);
        return success();
    }

    /**
     * 购物车列表
     */
    @GetMapping("/getGwcList")
    public AjaxResult getGwcList(TCart cart) {
        cart.setUserId(SecurityUtils.getUserIdStr());
        List<TCart> tCarts = tCartService.selectTCartList(cart);
        for (int i = 0; i < tCarts.size(); i++) {
            TCart tGwc = tCarts.get(i);
            String userIdStr = SecurityUtils.getUserIdStr();
            BigDecimal vipPrice = productService.getVipPrice(userIdStr, tGwc.getProductId());
            tCarts.get(i).setVipPrice(vipPrice);
         }
        return AjaxResult.success(tCarts);
    }



    /**
     * 修改头像
     */
    @PostMapping("/updateUser")
    public AjaxResult updateUser(@RequestBody UpdateUserDTO updateUserDTO) {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(SecurityUtils.getUserId());
        sysUser.setAvatar(updateUserDTO.getAvatar());
        sysUserService.updateUserApp(sysUser);
        return  AjaxResult.success();
    }


    /**
     * 查询数据字典
     */
    @GetMapping("/getDict")
    public AjaxResult getDict(String key) {
        SysDictData  sysDictData= new SysDictData();
        sysDictData.setDictType(key);
        List<SysDictData> dictCache = iSysDictDataService.selectDictDataList(sysDictData);
        return AjaxResult.success(dictCache);
    }

    /**
     * 获取小程序码
     */
    @GetMapping("/getEwmCode")
    public AjaxResult getEwmCode() throws Exception {
        String accessToken = this.getAccessToken();
        String ossUrl = MiniProgramCodeUtil.getMiniProgramCode(accessToken);
        return AjaxResult.success(ossUrl);
    }



    @Autowired
    private RedisService redisService;

    @GetMapping("/getAccessToken")
    public String getAccessToken() throws Exception {
//        Object cacheObject_token = redisService.getCacheObject("WX_TOKEN");
//        if(cacheObject_token!=null){
//            log.info("开始获取token=======================从缓存中获取token======================:"+cacheObject_token);
//            return String.valueOf(cacheObject_token);
//        }
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";

        String replaceUrl = url.replace("{0}", "wx5340c1916f7c4e89").replace("{1}", "97d9edb5eb747aea8964b9aae50fc83e");
        String res = HttpUtil.get(replaceUrl);
        JSONObject object = JSONObject.parseObject(res);
        Object access_token = object.get("access_token");
        String expires_in = object.get("expires_in").toString();
        redisService.setCacheObject("WX_TOKEN", access_token, Long.valueOf(expires_in), TimeUnit.SECONDS);
        return access_token.toString();
    }



}
